<?php

namespace Biz\service\brand;

use Biz\model\brand\ShopCity as mShopCity;
use Biz\model\brand\ShopAddres as mShopAddress;
use Doraemon\service\statSign\StatSign;
use Doraemon\tools\BlockType;
use Doraemon\tools\ImgUrl;
use Biz\cache\brand\shop;
use Doraemon\cache\UserCounter;
use Biz\model\brand\Brand;
use Doraemon\tools\Hhzurl;
use Doraemon\tools\LinkFormat;
use Doraemon\service\Location\Search;
use Hhz\AdministrativeRegion\Region;
use Hhzbeads\Img\ImageType;
use hhz\constant\basic\UserExtendPhoneScene;
use Doraemon\tools\Log;
use Doraemon\service\Member\PhoneCrypto;
use Doraemon\model\Phone as PhoneModel;


class BrandShop
{


    const GEO_MAP_PATH = '/community/map?longitude=%s&latitude=%s';

    /*获取城市信息
     * */
    public static function getCityList($brandId)
    {
        $info = mShopCity::getCityByBrandId($brandId);
        $result = [];
        if ($info && is_array($info)) {
            foreach ($info as $val) {
                $result [] = [
                    'id' => $val['id'],
                    'city_id' => $val['city_id'],
                    'city_name' => $val['city_name'],
                    'area_code' => $val['area_code'],
                    'area_name' => $val['area_name'],
                    'city_sort' => $val['city_sort']
                ];
            }
        }
        return $result;
    }

    /*添加城市信息
     * */
    public static function updateCityInfo($brandId, $city_info = [])
    {
        try {
            //获取原来的城市信息
            $info = mShopCity::getCityByBrandId($brandId);
            if ($city_info && is_array($city_info)) {
                $sort = count($city_info);
                $ids = [];
                foreach ($city_info as $val) {
                    if ($val['id']) {
                        $update_data = [
                            'edittime' => date("Y-m-d H:i:s", time()),
                            'city_sort' => $sort
                        ];
                        mShopCity::updateById($val['id'], $update_data);
                        $ids[] = $val['id'];
                    } else {
                        $areaName = Region::getNameByCode($val['area_code']);
                        $insert_data = [
                            'city_id' => Region::getOldCodeByCode($val['area_code']),
                            'city_name' => $areaName,

                            'area_code' => $val['area_code'],
                            'area_name' => $areaName,

                            'brand_id' => $brandId,
                            'addtime' => date("Y-m-d H:i:s"),
                            'city_sort' => $sort,
                            'city_status' => mShopAddress::STATUS_NORMAL
                        ];
                        mShopCity::addCityInfo($insert_data);
                    }
                    $sort--;
                }
                $delete_info = array_filter($info, function ($val) use ($ids) {
                    return (in_array($val['id'], $ids)) ? false : true;
                });
                if ($delete_info && is_array($delete_info)) {
                    foreach ($delete_info as $val) {
                        $delete_data = [
                            'edittime' => date("Y-m-d H:i:s", time()),
                            'city_status' => mShopCity::STATUS_DELETE
                        ];
                        mShopCity::updateById($val['id'], $delete_data);
                    }
                }
            } elseif ($info && is_array($info)) {
                $delete_ids = array_column($info, 'id');
                mShopCity::updateByWhere(['id' => $delete_ids],
                    ['city_status' => mShopCity::STATUS_DELETE, 'edittime' => date("Y-m-d H:i:s")]);
            }
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }


    /**
     * 获取信息
     * @param $brandId
     * @param $areaCode
     * @return array
     * @throws \Exception
     */
    public static function getAddressList($brandId, $areaCode)
    {
        $info = mShopAddress::getDataBywhere([
            'brand_id' => $brandId,
            'area_code' => $areaCode,
            'shop_status' => mShopAddress::STATUS_NORMAL
        ]);
        $result = [];
        if ($info && is_array($info)) {
            $phoneEncryptIds = array_column($info, 'phone_encrypt_id');
            $getDecryptPhones = $phoneEncryptIds ? self::batchGetDecryptPhones($phoneEncryptIds) : [];
            foreach ($info as $val) {
                $cover_pic_url = ImgUrl::getUrl(ImageType::APPTYPE_BIZ, $val['pic_id'],
                    ImageType::IMAGE_SIZE_ORI_PHONE_BIG);
                $areaName = Region::getNameByCode($val['area_code']);
                $result[] = [
                    'id' => $val['id'],
                    'brand_id' => $val['brand_id'],
                    'city_id' => $val['city_id'],
                    'city_name' => $val['city_name'],
                    'area_code' => $val['area_code'],
                    'area_name' => $areaName,
                    'name' => $val['name'],
                    'shop_time' => $val['shop_time'],
                    'pic_id' => $val['pic_id'],
                    'cover_pic_url' => $cover_pic_url,
                    'phone' => $getDecryptPhones[$val['phone_encrypt_id']] ?? '',
                    'address' => json_decode($val['address'], true),
                    'show_address' => $val['show_address']

                ];
            }
        }
        return $result;


    }

    /*添加信息
     *
     * */
    public static function editAddress($brandId, $areaCode, $areaName, $address_list)
    {
        try {
            //获取原来的城市信息
            $map = [];
            $map['AND'] = [
                'brand_id' => $brandId,
                'area_code' => $areaCode,
                'shop_status' => mShopAddress::STATUS_NORMAL
            ];
            $map['ORDER'] = ['shop_sort' => 'DESC'];
            $info = mShopAddress::getDataBywhere(
                $map
            );
            if ($address_list && is_array($address_list)) {
                $sort = count($address_list);
                $ids = [];
                foreach ($address_list as $val) {
                    $city_id = Region::getOldCodeByCode($areaCode);
                    if ($val['id']) {
                        $update_data = [
                            'name' => $val['name'],
                            'pic_id' => $val['pic_id'] ?: '',
                            'phone' => $val['phone'],
                            'shop_time' => $val['shop_time'] ?: '',
                            'address' => json_encode($val['address']),
                            'show_address' => $val['show_address'] ?: '',
                            'area_code' => $areaCode,
                            'area_name' => $areaName,
                            'city_id' => $city_id,
                            'city_name' => $areaName,
                            'brand_id' => $brandId,
                            'edittime' => date("Y-m-d H:i:s", time()),
                            'shop_sort' => $sort,
                            'shop_status' => mShopAddress::STATUS_NORMAL
                        ];
                        mShopAddress::updateById($val['id'], $update_data);
                        $ids[] = $val['id'];
                    } else {
                        $insert_data = [
                            'name' => $val['name'],
                            'pic_id' => $val['pic_id'],
                            'phone' => $val['phone'],
                            'shop_time' => $val['shop_time'],
                            'address' => json_encode($val['address']) ?: '',
                            'show_address' => $val['show_address'] ?: '',
                            'area_code' => $areaCode,
                            'area_name' => $areaName,
                            'city_id' => $city_id,
                            'city_name' => $areaName,
                            'brand_id' => $brandId,
                            'addtime' => date("Y-m-d H:i:s", time()),
                            'shop_sort' => $sort,
                            'shop_status' => mShopAddress::STATUS_NORMAL
                        ];
                        mShopAddress::addAddressInfo($insert_data);
                    }
                    $sort--;
                }
                if ($info && is_array($info)) {
                    $delete_info = array_filter($info, function ($val) use ($ids) {
                        return (in_array($val['id'], $ids)) ? false : true;
                    });
                    if ($delete_info && is_array($delete_info)) {
                        foreach ($delete_info as $val) {
                            $delete_data = [
                                'edittime' => date("Y-m-d H:i:s", time()),
                                'shop_status' => mShopAddress::STATUS_DELETE
                            ];
                            mShopAddress::updateById($val['id'], $delete_data);
                        }
                    }
                }
            } elseif ($info && is_array($info)) {
                $delete_ids = array_column($info, 'id');
                mShopAddress::updateByWhere(['id' => $delete_ids],
                    ['shop_status' => mShopAddress::STATUS_DELETE, 'edittime' => date("Y-m-d H:i:s", time())]);
            }
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }


    /**
     * 获取门店
     * @param $brandId
     * @param $version
     * @return array
     */
    public static function getShopInfo($brandId): array
    {
        $result = [];
        $city_info = mShopCity::getCityByBrandId($brandId);
        if ($city_info && is_array($city_info)) {
            $map = [
                'brand_id' => $brandId,
                'shop_status' => mShopAddress::STATUS_NORMAL,
                'ORDER' => ['shop_sort' => 'DESC'],
            ];
            $address_infos = mShopAddress::getDataBywhere($map);
            $areaShopList = [];
            $phoneEncryptIds = [];
            foreach ($address_infos as $row) {
                $areaShopList[$row['area_code']][] = $row;
                $phoneEncryptIds[] = $row['phone_encrypt_id'];
            }
            $getDecryptPhones = self::batchGetDecryptPhones($phoneEncryptIds);

            foreach ($city_info as $key => $city) {
                $address_info = $areaShopList[$city['area_code']];
                if ($address_info && is_array($address_info)) {
                    $result[$key] = [
                        'id' => $city['id'],
                        //todo 版本判断 几个版本后修改-开始
                        'city_id' => $city['city_id'],
                        'city_name' => $city['city_name'],
                        //todo 版本判断 几个版本后修改-结束
                        'area_code' => $city['area_code'],
                        'area_name' => $city['area_name'],
                    ];

                    foreach ($address_info as $address) {
                        $cover_pic_url = ImgUrl::getUrl(ImgUrl::APPTYPE_BIZ, $address['pic_id'],
                            ImgUrl::IMAGE_SIZE_ORI_NPHONE);
                        $address_detail = json_decode($address['address'], true);
                        $result[$key]['shop_list'][] = [
                            'id' => $address['id'],
                            'name' => $address['name'],
                            'cover_pic_url' => $cover_pic_url,
                            'phone' => $getDecryptPhones[$address['phone_encrypt_id']] ?? '',
                            'shop_time' => $address['shop_time'],
                            'show_address' => $address['show_address'],
                            'address_detail' => $address_detail,
                            'location' => $address_detail['location']
                        ];

                    }
                }

            }
        }
        return $result;
    }

    public static function batchGetDecryptPhones(array $phoneEncryptIds)
    {
        $result = [];
        $count = count($phoneEncryptIds);
        $pageSize = 300;
        for ($page = 0; ($page * $pageSize) < $count; $page++) {
            $ids = array_slice($phoneEncryptIds, $page * $pageSize, $pageSize);
            if ($ids) {
                $phones = PhoneModel::batchGetExtendPhone($ids, UserExtendPhoneScene::BRAND_SHOP_INFO_PHONE);
                $result = $result + $phones;
            }
        }
        return $result;
    }


    /*设置缓存
     *
     * */
    public static function setCacheByBrandId($brandId)
    {
        try {
            $result = self::getShopInfo($brandId);
            $result = json_encode($result);
            shop::setByBrandId($brandId, $result);
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * 获取门店列表
     * @param $user_location
     * @param $brandId
     * @return array|mixed
     */
    public static function getShopList($user_location = '', $brandId)
    {
        $list = [];
        try {
            $shop_info = self::getShopInfo($brandId);
            if ($user_location) {
                $user_location = json_decode($user_location, true);
                $address_info = Search::reverseLocation($user_location['lat'] . "," . $user_location['lng']);
                $first_info = [];
                foreach ($shop_info as $key => $city) {
//                    if (version_compare($version, "5.18.0", ">=")) {
                    $name = $city['area_name'] ?? '';
//                    } else {
//                        $name = $city['city_name'] ?? '';
//                    }

                    if ($address_info['city'] && (strpos($address_info['city'], $name) !== false || strpos($name, $address_info['city']) !== false)) {

                        $first_info[$key]['id'] = $city['id'];
//                        if (version_compare($version, "5.18.0", ">=")) {
                        $first_info[$key]['area_code'] = $city['area_code'];
                        $first_info[$key]['area_name'] = $city['area_name'];
//                        } else {
                        $first_info[$key]['city_id'] = $city['city_id'];
                        $first_info[$key]['city_name'] = $city['city_name'];
//                        }

                        $is_location = true;
                    } else {
                        $list[$key]['id'] = $city['id'];
//                        if (version_compare($version, "5.18.0", ">=")) {
                        $list[$key]['area_code'] = $city['area_code'];
                        $list[$key]['area_name'] = $city['area_name'];
//                        } else {
                        $list[$key]['city_id'] = $city['city_id'];
                        $list[$key]['city_name'] = $city['city_name'];
//                        }

                        $is_location = false;
                    }
                    if ($city['shop_list'] && is_array($city['shop_list'])) {
                        $shop_distance_list = [];
                        foreach ($city['shop_list'] as &$shop) {
                            if ($is_location) {
                                $distance = self::getDistance($user_location, $shop['location']);
                                $shop['distance'] = $distance . "km";
                                $shop_distance_list[] = $distance;
                            }
                            $link = sprintf(Hhzurl::getDomain() . self::GEO_MAP_PATH, $shop['location']['lng'],
                                    $shop['location']['lat']) . "&shop_name=" . urlencode($shop['name']) . "&address=" . urlencode($shop['show_address']) . "&distance=" . $shop['distance'] . "&hhzjump=1";
                            $shop['geo_link'] = LinkFormat::encryptionLink($link);
                            $shop['statSign'] = statSign::genStatSign(statSign::MODULE_BRAND_HOME_BRAND_SHOP_LIST, [
                                statSign::EXTEND_KEY_OBJ_ID => $shop['id'],
                                statSign::EXTEND_KEY_OBJ_TYPE => BlockType::TYPE_STORE,
                            ]);
                        }
                        $city['shop_list'] = \Doraemon\tools\StatSign::versionCompatible($city['shop_list'], \Doraemon\tools\StatSign::BRAND_UP_GRADE_VERSION_521, BlockType::TYPE_STORE, 'shop_info');
                        if ($is_location) {
                            array_multisort($shop_distance_list, SORT_ASC, $city['shop_list']);
                            $first_info[$key]['shop_list'] = $city['shop_list'];
                        } else {
                            if ($shop_distance_list) {
                                array_multisort($shop_distance_list, SORT_ASC, $city['shop_list']);
                            }
                            $list[$key]['shop_list'] = $city['shop_list'];
                        }
                    }
                }
                $list = array_merge($first_info, $list);
            } else {
                if ($shop_info && is_array($shop_info)) {
                    foreach ($shop_info as $key => &$city) {
                        if ($city['shop_list'] && is_array($city['shop_list'])) {
                            foreach ($city['shop_list'] as &$shop) {
                                $link = sprintf(Hhzurl::getDomain() . self::GEO_MAP_PATH, $shop['location']['lng'],
                                        $shop['location']['lat']) . "&shop_name=" . urlencode($shop['name']) . "&address=" . urlencode($shop['show_address']) . "&hhzjump=1";
                                $shop['geo_link'] = LinkFormat::encryptionLink($link);
                                $shop['statSign'] = statSign::genStatSign(statSign::MODULE_BRAND_HOME_BRAND_SHOP_LIST, [
                                    statSign::EXTEND_KEY_OBJ_ID => $shop['id'],
                                    statSign::EXTEND_KEY_OBJ_TYPE => BlockType::TYPE_STORE,
                                ]);
                            }
                            $city['shop_list'] = \Doraemon\tools\StatSign::versionCompatible($city['shop_list'], \Doraemon\tools\StatSign::BRAND_UP_GRADE_VERSION_521, BlockType::TYPE_STORE, 'shop_info');

                        }
                    }
                }
                $list = $shop_info;
            }
            return $list;
        } catch (\Exception $e) {
            return $list;
        }

    }


    /*
     *
     * */
    public static function getDistance($userLocation, $shopLocation)
    {
        $earthRadius = 6367000;
        $lat1 = ($userLocation['lat'] * pi()) / 180;
        $lng1 = ($userLocation['lng'] * pi()) / 180;
        $lat2 = ($shopLocation['lat'] * pi()) / 180;
        $lng2 = ($shopLocation['lng'] * pi()) / 180;
        $calcLongitude = $lng2 - $lng1;
        $calcLatitude = $lat2 - $lat1;
        $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
        $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
        $calculatedDistance = ($earthRadius * $stepTwo);
        return round($calculatedDistance / 1000);
    }


    /*set counter
     *
     * */
    public static function setShopCount($brandId)
    {
        try {
            $brand_info = Brand::getBrandInfoById($brandId);
            if (empty($brand_info)) {
                return false;
            }

            $city_info = mShopCity::getCityByBrandId($brandId);
            if ($city_info && is_array($city_info)) {
                $city_ids = array_filter(array_unique(array_column($city_info, 'area_code'))) ?: [];

                if ($city_ids && is_array($city_ids)) {
                    $map = [];
                    $map['AND'] = [
                        'brand_id' => $brandId,
                        'area_code' => $city_ids,
                        'shop_status' => mShopAddress::STATUS_NORMAL
                    ];
                    $count = mShopAddress::getShopCounterByMap($map) ?: 0;
                    if ($brand_info['uid']) {
                        UserCounter::setCounter($brand_info['uid'], [UserCounter::TYPE_SHOP => $count]);
                    }
                }
            }
            return true;
        } catch (\Exception $e) {
            return false;
        }

    }


}